/*
 * $Id: sem.c,v 1.3 2006-06-01 06:40:03 bacon Exp $
 */

#include <xp/bas/sem.h>
#include <xp/bas/memory.h>

xp_sem_t* xp_sem_open (xp_sem_t* sem, unsigned int init)
{
	if (sem == XP_NULL)
	{
		sem = (xp_sem_t*) xp_malloc (xp_sizeof(xp_sem_t));
		if (sem == XP_NULL) return XP_NULL;
		sem->__dynamic = xp_true;
	}
	else sem->__dynamic = xp_false;

#if defined(_WIN32)
	sem->hnd = CreateSemaphore (XP_NULL, 
		(LONG)init, XP_TYPE_MAX(LONG), XP_NULL);
	if (sem->hnd == NULL) 
	{
		if (sem->__dynamic) xp_free (sem);
		return XP_NULL;	
	}
#else
	if (sem_init (&sem->hnd, 0, init) == -1)
	{
		if (sem->__dynamic) xp_free (sem);
		return XP_NULL;	
	}
#endif

	return sem;
}

int xp_sem_close (xp_sem_t* sem)
{
#if defined(_WIN32)
	if (CloseHandle(sem->hnd) == 0) return -1;
#else
	if (sem_destroy(&sem->hnd) == -1) return -1;
#endif
	if (sem->__dynamic) xp_free (sem);
	return 0;
}

int xp_sem_acquire (xp_sem_t* sem)
{
#if defined(_WIN32)
	return (WaitForSingleObject (sem->hnd, INFINITE) == WAIT_FAILED)? -1: 0;
#else
	return sem_wait (&sem->hnd);	
#endif
}

int xp_sem_release (xp_sem_t* sem)
{
#if defined(_WIN32)
	return (ReleaseSemaphore (sem->hnd, 1, XP_NULL) == 0)? -1: 0;
#else
	return sem_post (&sem->hnd);	
#endif
}
